package com.personal.core.utils;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;

import com.personal.core.exchange.ConvertFactory;
import com.personal.core.exchange.Convertor;

/**
 * 类型转换
 * @author cuibo
 *
 */
public class ConvertUtil
{
    
    public static <T> T mapTObject(Map<String, ? extends Object> map, T t)
    {
        if (map == null || t == null)
        {
            return null;
        }
        try
        {
            BeanUtils.populate(t, map);
        } catch (IllegalAccessException | InvocationTargetException e)
        {
            e.printStackTrace();
        }
        return t;
    }
    
    public static <T> T mapTObject(Map<String, ? extends Object> map, Class<T> t)
    {
        if (map == null || t == null)
            return null;
        T result = null;
        try
        {
            result = t.newInstance();
        } catch (InstantiationException | IllegalAccessException e)
        {
            e.printStackTrace();
            return null;
        }
        try
        {
            BeanUtils.populate(result, map);
        } catch (IllegalAccessException | InvocationTargetException e)
        {
            e.printStackTrace();
        }
        return result;
    }

    public static Map<String, Object> objectToMap(Object obj)
    {
        if (obj == null)
            return null;

        Map<String, Object> map = new HashMap<String, Object>();
        PropertyDescriptor[] propertyDescriptors = null;
        try
        {
            propertyDescriptors = IntrospectorUtil.getPropertyDescriptors(obj.getClass());
        } catch (IntrospectionException e1)
        {
            e1.printStackTrace();
        }
        if (propertyDescriptors == null)
        {
            return null;
        }
        for (PropertyDescriptor property : propertyDescriptors)
        {
            String key = property.getName();
            if (key.compareToIgnoreCase("class") == 0)
            {
                continue;
            }
            Method getter = property.getReadMethod();
            try
            {
                Object value = getter != null ? getter.invoke(obj) : null;
                map.put(key, value);
            } catch (IllegalAccessException e)
            {
                e.printStackTrace();
            } catch (IllegalArgumentException e)
            {
                e.printStackTrace();
            } catch (InvocationTargetException e)
            {
                e.printStackTrace();
            }
        }
        return map;
    }

    public static Object transformObject(Object value, Class<?> targetClass)
    {
        return ConvertFactory.getFactory().exchange(value, targetClass);
    }

    public static Object transformObjectCatchException(Object value, Class<?> targetClass)
    {
        try
        {
            return ConvertFactory.getFactory().exchange(value, targetClass);
        } catch (Exception e)
        {
            return null;
        }
    }

    public static <T> T transformObject(Object value, Class<T> targetClass, T defaultValue)
    {
        return ConvertFactory.getFactory().exchange(value, targetClass, defaultValue);
    }

    public static <T> T transformObjectCatchException(Object value, Class<T> targetClass, T defaultValue)
    {
        try
        {
            return ConvertFactory.getFactory().exchange(value, targetClass, defaultValue);
        } catch (Exception e)
        {
            return defaultValue;
        }
    }

    public static void addConvertor(Convertor<?, ?> convertor)
    {
        ConvertFactory.getFactory().addConvertor(convertor);
    }

}
